/**
 * 
 */
package inz.common;

import inz.model.patterns.Itemset;
import inz.model.patterns.Sequence;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

/** Class manages operations related with files: finding, opening, scanning */
public class IOManager
{
	public static final String WORDS_DELIM_REGEX = "[\\W]+";
	public static final String WORDS_NO_NUMBERS_DELIM_REGEX = "[^\\p{L}]+";
	public static final String URL_DELIM_REGEX = "http://";
	public static final String COMA_DELIM = ",";

	public static final String TXT = ".txt";

	private static Logger logger = Logger.getLogger(LoggingModule.GENERAL_LOGGER);

	/** @param file file to scan
	 * @param regex token delimeter
	 * @return scanner
	 * @throws FileNotFoundException */
	public static Scanner getFileScanner(File file, String regex) throws FileNotFoundException
	{
		return getFileScanner(file, regex, null);
	}

	/** @param file file to scan
	 * @param regex token delimeter
	 * @param flags flags of scanner (like case insensitive)
	 * @return scanner
	 * @throws FileNotFoundException */
	public static Scanner getFileScanner(File file, String regex, Integer flags) throws FileNotFoundException
	{
		Scanner fileScanner;
		fileScanner = new Scanner(file);
		if (flags != null)
		{
			fileScanner.useDelimiter(Pattern.compile(regex, flags));
		}
		else
		{
			fileScanner.useDelimiter(Pattern.compile(regex));
		}
		return fileScanner;
	}

	/** @param path path to file to scan
	 * @param regex token delimeter regex
	 * @return scanner
	 * @throws FileNotFoundException */
	public static Scanner getFileScanner(String path, String regex) throws FileNotFoundException
	{
		return getFileScanner(new File(path), regex);
	}

	/** @param inputString string to scan
	 * @param regex token delimeter regex
	 * @return scanner */
	public static Scanner getStringScanner(String inputString, String regex)
	{
		Scanner fileScanner;
		fileScanner = new Scanner(inputString);
		fileScanner.useDelimiter(regex);
		return fileScanner;
	}

	/** @param path path to file to scan
	 * @param regex token delimeter regex
	 * @param flags flags of scanner (like case insensitive)
	 * @return scanner
	 * @throws FileNotFoundException */
	public static Scanner getFileScanner(String path, String regex, Integer flags) throws FileNotFoundException
	{
		return getFileScanner(new File(path), regex, flags);
	}

	/** @param path path to directory
	 * @param type type of files to look
	 * @return array of files of given type from given directory */
	public static File[] getDirFiles(String path, String type)
	{
		File folder = new File(path);
		return folder.listFiles(new FilenameFilter()
		{
			@Override
			public boolean accept(File dir, String filename)
			{
				return filename.toLowerCase().endsWith(".txt");
			}
		});
	}

	/** @param fileName file containing urls
	 * @return list of urls */
	public static Set<String> extractUrls(String fileName)
	{
		Set<String> urls = new LinkedHashSet<String>();
		try
		{
			Integer flags = new Integer(Pattern.CASE_INSENSITIVE);
			Scanner fileScanner = IOManager.getFileScanner(fileName, IOManager.URL_DELIM_REGEX, flags);
			while (fileScanner.hasNext())
			{
				urls.add(URL_DELIM_REGEX + fileScanner.next().trim());
			}
		}
		catch (FileNotFoundException e)
		{
			// TODO komunikat o braku pliku
			e.printStackTrace();
		}
		return urls;

	}

	/** Loads contents from given web pages and saves them in files
	 * @param dirName name of directore to save contents of web pages
	 * @param urls set of web pages urls */
	public static void extractContentsAndSave(Set<String> urls, String dirName)
	{
		int k = 0;
		for (String url : urls)
		{
			Document doc;
			try
			{
				doc = Jsoup.connect(url).get();
				k++;
				BufferedWriter writer = new BufferedWriter(new FileWriter(dirName + k + ".txt"));
				writer.write(doc.text());
				writer.close();
				logger.log(Level.INFO, "sequence from: " + url + " added.", "urls");
			}
			catch (IOException e)
			{
				logger.log(Level.INFO, "error loading : " + url, "urls");
				e.printStackTrace();
			}
		}
	}

	public static List<String> customUrlExtractor(String fileName)
	{
		List<String> urls = new ArrayList<String>();
		String url = "";
		try
		{
			BufferedReader reader = new BufferedReader(new FileReader(fileName));
			String strLine;
			while ((strLine = reader.readLine()) != null)
			{
				url = strLine.subSequence(strLine.indexOf('(') + 1, strLine.indexOf(')')).toString();
				urls.add(url);
			}
			reader.close();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		return urls;
	}

	/** custom processing of file
	 * @param fileName text file to process */
	public static void customFileProcessing(String fileName)
	{
		try
		{
			BufferedReader reader = new BufferedReader(new FileReader(fileName));
			BufferedWriter writer = new BufferedWriter(new FileWriter("roboczy\\grzyby1opisy.txt"));
			String strLine, opisGrzyba = "";
			int k = 0;
			while ((strLine = reader.readLine()) != null)
			{
				if (strLine.length() < 3)
				{
					continue;
				}
				if (Character.isDigit(strLine.charAt(0)))
				{
					k++;
					writer.write(opisGrzyba + System.getProperty("line.separator"));
					opisGrzyba = "";
				}
				else
				{
					opisGrzyba += strLine + " ";
				}
			}
			System.out.println(k + " grzybow");
			writer.close();
			reader.close();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	/** @param fileName file with data
	 * @return set of stings (every line is one string) */
	public static Set<String> loadFromFile(String fileName)
	{
		Set<String> resultSet = new LinkedHashSet<String>();
		try
		{
			BufferedReader reader = new BufferedReader(new FileReader(fileName));
			String strLine;
			while ((strLine = reader.readLine()) != null)
			{
				resultSet.add(strLine.trim());
			}
			reader.close();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		return resultSet;
	}

	/** Loads ready, previously computed sequences from file
	 * @param fileName
	 * @return set of sequences */
	public static List<Sequence> loadSequences(String fileName, int howMany)
	{
		List<Sequence> resultList = new ArrayList<Sequence>();
		try
		{
			BufferedReader reader = new BufferedReader(new FileReader(fileName));
			String strLine;
			int loaded = 0;
			while ((strLine = reader.readLine()) != null && loaded < howMany)
			{
				List<Itemset> itemsets = new ArrayList<Itemset>();
				String[] elems = strLine.split("#");
				for (String elem : elems)
				{
					String[] items = elem.split(",");
					Itemset itemset = new Itemset(Arrays.asList(items));
					itemsets.add(itemset);
				}
				Sequence seq = new Sequence(itemsets);
				resultList.add(seq);
				loaded++;
			}
			reader.close();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		return resultList;
	}

	public static void main(String[] args)
	{
		System.out.println("hello static class main");
		customFileProcessing("roboczy\\grzyby.txt");
		// try
		// {
		// Document doc = Jsoup
		// .connect("http://www.kki.pl/zenit/grzyby_spyt/opisy.htm").get();
		// BufferedWriter writer = new BufferedWriter(new FileWriter("roboczy\\grzyby2.txt"));
		// for (Element e : doc.getElementsByTag("p"))
		// {
		// if (e.text().contains("zamknij"))
		// {
		// writer.write(System.getProperty("line.separator") + e.text() + System.getProperty("line.separator"));
		// }
		// else
		// {
		// writer.write(e.text() + System.getProperty("line.separator"));
		// }
		// }
		// writer.close();
		//
		// }
		// catch (IOException e)
		// {
		// e.printStackTrace();
		// }
	}
}
